<template>
    <n-card>
        <template #header>
            <div class="respondents">
                <n-avatar
                    :round="true"
                    :size="36"
                    :style="{color: 'white', backgroundColor: 'orange', fontSize: '18px'}"
                >{{ answer.username.toString().substring(0, 1) }}
                </n-avatar>
                <n-text class="name" style="font-weight: bold;" type="success">{{ answer.username }}</n-text>
                <n-text class="time" depth="3">发布于 {{
                        $dayjs(answer.createTime).format('YYYY-MM-DD HH:mm:ss')
                    }}
                </n-text>
            </div>
        </template>
        <template #header-extra>
            <n-button v-if="isQuestioner && !isSolved && !isAccept" tertiary type="primary" @click="handleAccept">
                <template #icon>
                    <n-icon>
                        <SmileBeamRegular/>
                    </n-icon>
                </template>
                采纳
            </n-button>
            <n-button v-else-if="answer.isAccepted || isAccept" :round="true" size="small" type="primary"
                      @click="handleAccept">
                <template #icon>
                    <n-icon>
                        <check/>
                    </n-icon>
                </template>
                已被采纳
            </n-button>
        </template>
        <n-space :vertical="true" size="large">
            <div v-highlight class="content" v-html="answerContentToHtml"></div>
            <n-switch v-model:value="showSupplement">
                <template #checked>
                    展开
                </template>
                <template #unchecked>
                    折叠
                </template>
            </n-switch>
            <n-collapse-transition :show="showSupplement">
                <n-descriptions :column="2" label-placement="left" title="补充说明">
                    <n-descriptions-item v-if="answer.modifiedCode" label="修改后的代码">
                        <n-ellipsis :tooltip="false" expand-trigger="click" line-clamp="4">
                            <n-code :code="answer.modifiedCode" :language="programming_language" :word-wrap="true"/>
                        </n-ellipsis>
                    </n-descriptions-item>
                    <n-descriptions-item v-if="answer.errorCode" label="出错代码">
                        <n-ellipsis :tooltip="false" expand-trigger="click" line-clamp="4">
                            <n-code :code="answer.errorCode" :language="programming_language" :word-wrap="true"/>
                        </n-ellipsis>
                    </n-descriptions-item>
                    <n-descriptions-item v-if="answer.errorType" label="错误类型">
                        {{ answer.errorType }}
                    </n-descriptions-item>
                    <n-descriptions-item v-if="answer.errorDesc" label="错误分析">
                        {{ answer.errorDesc }}
                    </n-descriptions-item>
                    <n-descriptions-item v-if="answer.errorRow" label="出错的行">
                        {{ answer.errorRow }}
                    </n-descriptions-item>
                    <n-descriptions-item v-if="answer.errorColumn" label="出错的列">
                        {{ answer.errorColumn }}
                    </n-descriptions-item>
                    <n-descriptions-item v-if="answer.codeBeforeChange" label="变化前的代码">
                        <n-ellipsis :tooltip="false" expand-trigger="click" line-clamp="4">
                            <n-code :code="answer.codeBeforeChange" :language="programming_language"
                                    :word-wrap="true"/>
                        </n-ellipsis>
                    </n-descriptions-item>
                    <n-descriptions-item v-if="answer.codeAfterChange" label="变化后的代码">
                        <n-ellipsis :tooltip="false" expand-trigger="click" line-clamp="4">
                            <n-code :code="answer.codeAfterChange" :language="programming_language"
                                    :word-wrap="true"/>
                        </n-ellipsis>
                    </n-descriptions-item>
                </n-descriptions>
            </n-collapse-transition>
        </n-space>
        <template #footer>
            <n-space size="small">
                <n-button v-if="isAgree" color="#18a058" @click="toggleAgree(answer.id)">
                    <template #icon>
                        <n-icon>
                            <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"
                                 xmlns:xlink="http://www.w3.org/1999/xlink">
                                <path
                                    d="M273 495.9v428l.3-428zm538.2-88.3H496.8l9.6-198.4c.6-11.9-4.7-23.1-14.6-30.5c-6.1-4.5-13.6-6.8-21.1-6.7c-19.6.1-36.9 13.4-42.2 32.3c-37.1 134.4-64.9 235.2-83.5 302.5V852h399.4a56.85 56.85 0 0 0 33.6-51.8c0-9.7-2.3-18.9-6.9-27.3l-13.9-25.4l21.9-19a56.76 56.76 0 0 0 19.6-43c0-9.7-2.3-18.9-6.9-27.3l-13.9-25.4l21.9-19a56.76 56.76 0 0 0 19.6-43c0-9.7-2.3-18.9-6.9-27.3l-14-25.5l21.9-19a56.76 56.76 0 0 0 19.6-43c0-19.1-11-37.5-28.8-48.4z"
                                    fill="currentColor" fill-opacity=".15"></path>
                                <path
                                    d="M112 528v364c0 17.7 14.3 32 32 32h65V496h-65c-17.7 0-32 14.3-32 32zm773.9 5.7c16.8-22.2 26.1-49.4 26.1-77.7c0-44.9-25.1-87.5-65.5-111a67.67 67.67 0 0 0-34.3-9.3H572.3l6-122.9c1.5-29.7-9-57.9-29.5-79.4a106.4 106.4 0 0 0-77.9-33.4c-52 0-98 35-111.8 85.1l-85.8 310.8l-.3 428h472.1c9.3 0 18.2-1.8 26.5-5.4c47.6-20.3 78.3-66.8 78.3-118.4c0-12.6-1.8-25-5.4-37c16.8-22.2 26.1-49.4 26.1-77.7c0-12.6-1.8-25-5.4-37c16.8-22.2 26.1-49.4 26.1-77.7c0-12.6-1.8-25-5.4-37zM820.4 499l-21.9 19l14 25.5a56.2 56.2 0 0 1 6.9 27.3c0 16.5-7.1 32.2-19.6 43l-21.9 19l13.9 25.4a56.2 56.2 0 0 1 6.9 27.3c0 16.5-7.1 32.2-19.6 43l-21.9 19l13.9 25.4a56.2 56.2 0 0 1 6.9 27.3c0 22.4-13.2 42.6-33.6 51.8H345V506.8c18.6-67.2 46.4-168 83.5-302.5a44.28 44.28 0 0 1 42.2-32.3c7.5-.1 15 2.2 21.1 6.7c9.9 7.4 15.2 18.6 14.6 30.5l-9.6 198.4h314.4C829 418.5 840 436.9 840 456c0 16.5-7.1 32.2-19.6 43z"
                                    fill="currentColor"></path>
                            </svg>
                        </n-icon>
                    </template>
                    已赞同 {{ answer.voteCount === 0 ? '' : answer.voteCount }}
                </n-button>
                <n-button v-else secondary type="primary" @click="toggleAgree(answer.id)">
                    <template #icon>
                        <n-icon>
                            <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"
                                 xmlns:xlink="http://www.w3.org/1999/xlink">
                                <path
                                    d="M273 495.9v428l.3-428zm538.2-88.3H496.8l9.6-198.4c.6-11.9-4.7-23.1-14.6-30.5c-6.1-4.5-13.6-6.8-21.1-6.7c-19.6.1-36.9 13.4-42.2 32.3c-37.1 134.4-64.9 235.2-83.5 302.5V852h399.4a56.85 56.85 0 0 0 33.6-51.8c0-9.7-2.3-18.9-6.9-27.3l-13.9-25.4l21.9-19a56.76 56.76 0 0 0 19.6-43c0-9.7-2.3-18.9-6.9-27.3l-13.9-25.4l21.9-19a56.76 56.76 0 0 0 19.6-43c0-9.7-2.3-18.9-6.9-27.3l-14-25.5l21.9-19a56.76 56.76 0 0 0 19.6-43c0-19.1-11-37.5-28.8-48.4z"
                                    fill="currentColor" fill-opacity=".15"></path>
                                <path
                                    d="M112 528v364c0 17.7 14.3 32 32 32h65V496h-65c-17.7 0-32 14.3-32 32zm773.9 5.7c16.8-22.2 26.1-49.4 26.1-77.7c0-44.9-25.1-87.5-65.5-111a67.67 67.67 0 0 0-34.3-9.3H572.3l6-122.9c1.5-29.7-9-57.9-29.5-79.4a106.4 106.4 0 0 0-77.9-33.4c-52 0-98 35-111.8 85.1l-85.8 310.8l-.3 428h472.1c9.3 0 18.2-1.8 26.5-5.4c47.6-20.3 78.3-66.8 78.3-118.4c0-12.6-1.8-25-5.4-37c16.8-22.2 26.1-49.4 26.1-77.7c0-12.6-1.8-25-5.4-37c16.8-22.2 26.1-49.4 26.1-77.7c0-12.6-1.8-25-5.4-37zM820.4 499l-21.9 19l14 25.5a56.2 56.2 0 0 1 6.9 27.3c0 16.5-7.1 32.2-19.6 43l-21.9 19l13.9 25.4a56.2 56.2 0 0 1 6.9 27.3c0 16.5-7.1 32.2-19.6 43l-21.9 19l13.9 25.4a56.2 56.2 0 0 1 6.9 27.3c0 22.4-13.2 42.6-33.6 51.8H345V506.8c18.6-67.2 46.4-168 83.5-302.5a44.28 44.28 0 0 1 42.2-32.3c7.5-.1 15 2.2 21.1 6.7c9.9 7.4 15.2 18.6 14.6 30.5l-9.6 198.4h314.4C829 418.5 840 436.9 840 456c0 16.5-7.1 32.2-19.6 43z"
                                    fill="currentColor"></path>
                            </svg>
                        </n-icon>
                    </template>
                    赞同 {{ answer.voteCount === 0 ? '' : answer.voteCount }}
                </n-button>
                <n-button v-if="isOppose" color="#747A81" @click="toggleOppose(answer.id)">
                    <template #icon>
                        <n-icon>
                            <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"
                                 xmlns:xlink="http://www.w3.org/1999/xlink">
                                <path
                                    d="M273 100.1v428h.3l-.3-428zM820.4 525l-21.9-19l14-25.5a56.2 56.2 0 0 0 6.9-27.3c0-16.5-7.1-32.2-19.6-43l-21.9-19l13.9-25.4a56.2 56.2 0 0 0 6.9-27.3c0-16.5-7.1-32.2-19.6-43l-21.9-19l13.9-25.4a56.2 56.2 0 0 0 6.9-27.3c0-22.4-13.2-42.6-33.6-51.8H345v345.2c18.6 67.2 46.4 168 83.5 302.5a44.28 44.28 0 0 0 42.2 32.3c7.5.1 15-2.2 21.1-6.7c9.9-7.4 15.2-18.6 14.6-30.5l-9.6-198.4h314.4C829 605.5 840 587.1 840 568c0-16.5-7.1-32.2-19.6-43z"
                                    fill="currentColor" fill-opacity=".15"></path>
                                <path
                                    d="M112 132v364c0 17.7 14.3 32 32 32h65V100h-65c-17.7 0-32 14.3-32 32zm773.9 358.3c3.6-12 5.4-24.4 5.4-37c0-28.3-9.3-55.5-26.1-77.7c3.6-12 5.4-24.4 5.4-37c0-28.3-9.3-55.5-26.1-77.7c3.6-12 5.4-24.4 5.4-37c0-51.6-30.7-98.1-78.3-118.4a66.1 66.1 0 0 0-26.5-5.4H273l.3 428l85.8 310.8C372.9 889 418.9 924 470.9 924c29.7 0 57.4-11.8 77.9-33.4c20.5-21.5 31-49.7 29.5-79.4l-6-122.9h239.9c12.1 0 23.9-3.2 34.3-9.3c40.4-23.5 65.5-66.1 65.5-111c0-28.3-9.3-55.5-26.1-77.7zm-74.7 126.1H496.8l9.6 198.4c.6 11.9-4.7 23.1-14.6 30.5c-6.1 4.5-13.6 6.8-21.1 6.7a44.28 44.28 0 0 1-42.2-32.3c-37.1-134.4-64.9-235.2-83.5-302.5V172h399.4a56.85 56.85 0 0 1 33.6 51.8c0 9.7-2.3 18.9-6.9 27.3l-13.9 25.4l21.9 19a56.76 56.76 0 0 1 19.6 43c0 9.7-2.3 18.9-6.9 27.3l-13.9 25.4l21.9 19a56.76 56.76 0 0 1 19.6 43c0 9.7-2.3 18.9-6.9 27.3l-14 25.5l21.9 19a56.76 56.76 0 0 1 19.6 43c0 19.1-11 37.5-28.8 48.4z"
                                    fill="currentColor"></path>
                            </svg>
                        </n-icon>
                    </template>
                </n-button>
                <n-button v-else secondary type="tertiary" @click="toggleOppose(answer.id)">
                    <template #icon>
                        <n-icon>
                            <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"
                                 xmlns:xlink="http://www.w3.org/1999/xlink">
                                <path
                                    d="M273 100.1v428h.3l-.3-428zM820.4 525l-21.9-19l14-25.5a56.2 56.2 0 0 0 6.9-27.3c0-16.5-7.1-32.2-19.6-43l-21.9-19l13.9-25.4a56.2 56.2 0 0 0 6.9-27.3c0-16.5-7.1-32.2-19.6-43l-21.9-19l13.9-25.4a56.2 56.2 0 0 0 6.9-27.3c0-22.4-13.2-42.6-33.6-51.8H345v345.2c18.6 67.2 46.4 168 83.5 302.5a44.28 44.28 0 0 0 42.2 32.3c7.5.1 15-2.2 21.1-6.7c9.9-7.4 15.2-18.6 14.6-30.5l-9.6-198.4h314.4C829 605.5 840 587.1 840 568c0-16.5-7.1-32.2-19.6-43z"
                                    fill="currentColor" fill-opacity=".15"></path>
                                <path
                                    d="M112 132v364c0 17.7 14.3 32 32 32h65V100h-65c-17.7 0-32 14.3-32 32zm773.9 358.3c3.6-12 5.4-24.4 5.4-37c0-28.3-9.3-55.5-26.1-77.7c3.6-12 5.4-24.4 5.4-37c0-28.3-9.3-55.5-26.1-77.7c3.6-12 5.4-24.4 5.4-37c0-51.6-30.7-98.1-78.3-118.4a66.1 66.1 0 0 0-26.5-5.4H273l.3 428l85.8 310.8C372.9 889 418.9 924 470.9 924c29.7 0 57.4-11.8 77.9-33.4c20.5-21.5 31-49.7 29.5-79.4l-6-122.9h239.9c12.1 0 23.9-3.2 34.3-9.3c40.4-23.5 65.5-66.1 65.5-111c0-28.3-9.3-55.5-26.1-77.7zm-74.7 126.1H496.8l9.6 198.4c.6 11.9-4.7 23.1-14.6 30.5c-6.1 4.5-13.6 6.8-21.1 6.7a44.28 44.28 0 0 1-42.2-32.3c-37.1-134.4-64.9-235.2-83.5-302.5V172h399.4a56.85 56.85 0 0 1 33.6 51.8c0 9.7-2.3 18.9-6.9 27.3l-13.9 25.4l21.9 19a56.76 56.76 0 0 1 19.6 43c0 9.7-2.3 18.9-6.9 27.3l-13.9 25.4l21.9 19a56.76 56.76 0 0 1 19.6 43c0 9.7-2.3 18.9-6.9 27.3l-14 25.5l21.9 19a56.76 56.76 0 0 1 19.6 43c0 19.1-11 37.5-28.8 48.4z"
                                    fill="currentColor"></path>
                            </svg>
                        </n-icon>
                    </template>
                </n-button>
                <n-button quaternary type="tertiary" @click="handleComment">
                    <template #icon>
                        <n-icon size="small">
                            <Comment/>
                        </n-icon>
                    </template>
                    回复
                </n-button>
                <n-button v-if="isCollected" quaternary type="primary" @click="handleCollect">
                    <template #icon>
                        <n-icon size="small">
                            <Star/>
                        </n-icon>
                    </template>
                    已收藏
                </n-button>
                <n-button v-else quaternary type="tertiary" @click="handleCollect">
                    <template #icon>
                        <n-icon size="small">
                            <Star/>
                        </n-icon>
                    </template>
                    收藏
                </n-button>
            </n-space>
            <n-card v-if="showCommentInput" :bordered="false" :embedded="true" size="small">
                <n-input
                    v-model:value="comment.content"
                    :autosize="true"
                    placeholder="询问细节或提出修改意见"
                    type="textarea"
                />
                <template #footer>
                    <n-text depth="3">如果对你有帮助，记得点赞支持</n-text>
                    <n-button style="float:right;" type="primary" @click="handleSubmitComment">提交评论</n-button>
                </template>
            </n-card>
            <n-card v-if="comments.length" :bordered="false" :embedded="true" style="margin-top: 1vh;">
                <n-space :vertical="true">
                    <template v-for="item in comments" :key="item.id">
                        <n-comment :comment="item" @update-comment-list="updateCommentList"></n-comment>
                    </template>
                </n-space>
            </n-card>
        </template>
    </n-card>
</template>

<style scoped>
.respondents {
    display: flex;
    align-items: center;
    gap: 0.5vw;
    font-size: 15px;
}

.content {
    font-size: 15px;
}
</style>

<script setup>
import { Check, Comment, SmileBeamRegular, Star } from '@vicons/fa'
import { computed, onMounted, ref, watch } from 'vue'
import { deleteVoteOfAnswer, getUserVoteOfAnswer, insertVoteOfAnswer, updateVoteOfAnswer } from '../api/vote'
import { useUserStore } from '../store/user'
import { useLoadingBar, useMessage } from 'naive-ui'
import { useRoute } from 'vue-router'
import { insertComment, listComments } from '../api/comment'
import NComment from '../components/Comment.vue'
import { marked } from 'marked'
import { partialUpdateQuestion } from '../api/question'
import { updateAnswer } from '../api/answer'
import { partialUpdateUser } from '../api/user'
import { getCollectionByAnswerId, insertCollection, removeCollection } from '../api/collections'

const props = defineProps({
    answer: {
        id: Number,
        content: String,
        questionId: Number,
        username: String,
        createTime: Date,
        voteCount: Number,
        isAccepted: Boolean,
        userId: Number,
        modifiedCode: String,
        errorCode: String,
        errorType: String,
        errorDesc: String,
        errorColumn: String,
        errorRow: String,
        codeBeforeChange: String,
        codeAfterChange: String,
    },
    isQuestioner: Boolean,
    isSolved: Boolean,
    reward: Number,
    programmingLanguage: String,
})
const userStore = useUserStore()
const message = useMessage()
const answerVote = ref({
    entityType: 1,
    entityId: null,
    voter: null,
    attitude: 'neutral',
})
const voteId = ref(null)

const isAgree = ref(false)
const isOppose = ref(false)
const toggleAgree = answerId => {
    if (userStore.token === '') {
        message.warning('你还没有登录，请登录后再试！')
        return
    }
    isAgree.value = !isAgree.value
    if (isOppose.value && isAgree.value) {
        isOppose.value = false
    }
    answerVote.value.entityId = answerId
    if (isAgree.value && !isOppose.value && voteId.value !== null) {
        updateVoteOfAnswer(answerId, voteId.value).then(res => {
            if (res.code === '200') {
                props.answer.voteCount += 1
            }
        })
        return
    }
    if (isAgree.value) {
        answerVote.value.attitude = 'approval'
        insertVoteOfAnswer(answerId, answerVote.value).then(res => {
            if (res.code === '201') {
                props.answer.voteCount += 1
                voteId.value = res.data
            }
        })
    } else {
        deleteVoteOfAnswer(answerId, voteId.value).then(res => {
            if (res.code === '204') {
                isAgree.value = false
                props.answer.voteCount -= 1
            } else {
                message.error('出问题啦！')
            }
        })
    }
}
const toggleOppose = answerId => {
    if (userStore.token === '') {
        message.warning('你还没有登录，请登录后再试！')
        return
    }
    isOppose.value = !isOppose.value
    if (isOppose.value && isAgree.value) {
        isAgree.value = false
    }
    if (!isAgree.value && isOppose.value) {
        updateVoteOfAnswer(answerId, voteId.value).then(res => {
            props.answer.voteCount -= 1
        })
        return
    }
    answerVote.value.entityId = answerId
    if (isOppose.value) {
        answerVote.value.attitude = 'disapproval'
        insertVoteOfAnswer(answerId, answerVote.value).then(res => {
            if (res.code === '201') {
                props.answer.voteCount = res.data
            }
        })
    } else {
        deleteVoteOfAnswer(answerId, voteId.value).then(res => {
            if (res.code === '204') {
                isAgree.value = false
            } else {
                message.error('出问题啦！')
            }
        })
    }
}

const comments = ref([])

onMounted(() => {
        listComments(props.answer.id).then(res => {
            comments.value = res.data
        })
        if (userStore.token !== '') {
            getUserVoteOfAnswer(props.answer.id).then(res => {
                if (res.data === null) return
                voteId.value = res.data.id
                if (res.data.attitude === 'approval') {
                    isAgree.value = true
                } else if (res.data.attitude === 'disapproval') {
                    isOppose.value = true
                } else {
                    isAgree.value = false
                    isOppose.value = false
                }
            })
            getCollectionByAnswerId(props.answer.id).then(res => {
                if (res.code === '200' && res.data !== null) {
                    isCollected.value = true
                    collection.value.id = res.data.id
                } else {
                    isCollected.value = false
                }
            })
        }

    },
)

const route = useRoute()
const comment = ref({
    content: '',
    questionId: route.params.id,
    answerId: props.answer.id,
    rootCommentId: null,
    replyTo: null,
    createTime: null,
})
const showCommentInput = ref(false)
const handleComment = () => {
    showCommentInput.value = !showCommentInput.value
}
const handleSubmitComment = () => {
    if (userStore.token === '') {
        message.warning('你还没登录，请登录后再试！')
    } else if (comment.value.content === '') {
        message.warning('你还没有写评论！')
    } else {
        insertComment(comment.value, props.answer.id).then(res => {
            if (res.code === '201') {
                message.success('评论成功！')
                comment.value.content = ''
                updateCommentList(props.answer.id)
            } else {
                message.error('出错啦！')
            }
        })
    }
}
const updateCommentList = async (answerId) => {
    await listComments(answerId).then(res => {
        comments.value = res.data
    })
}

const answerContentToHtml = computed(() => {
        return marked.parse(props.answer.content)
    },
)

const isAccept = ref(props.answer.isAccepted)
const loadingBar = useLoadingBar()
const handleAccept = async () => {
    isAccept.value = !isAccept.value
    loadingBar.start()
    await partialUpdateQuestion(route.params.id, { isSolved: isAccept.value })
    await updateAnswer(props.answer.id, { isAccepted: isAccept.value }).then(res => {
        isAccept.value = res.data.isAccepted
    })
    if (isAccept.value) {
        await partialUpdateUser(props.answer.userId, { credit: props.reward + userStore.credit })
    } else {
        await partialUpdateUser(props.answer.userId, { credit: userStore.credit })
    }
    loadingBar.finish()
}

const isCollected = ref(false)
const collection = ref({
    id: null,
    answerId: props.answer.id,
})
const handleCollect = () => {
    if (userStore.token) {
        isCollected.value = !isCollected.value
        if (isCollected.value) {
            insertCollection(collection.value).then(res => {
                if (res.code === '201') {
                    collection.value.id = res.data.id
                    message.success('收藏成功！')
                }
            })
        } else {
            removeCollection(collection.value.id).then(res => {
                if (res.code === '204') {
                    message.info('已取消收藏！')
                }
            })
        }
    } else {
        message.warning('请登录后再收藏！')
    }

}

const showSupplement = ref(false)
const programming_language = ref('C++')
watch(() => props.programmingLanguage,
    (newValue, oldValue) => {
        programming_language.value = newValue
    },
)
</script>

